package controller;

import entity.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.bind.support.SessionStatus;

import javax.servlet.http.HttpSession;

/**
 * Author:shixiaojun@itany.com
 * Date:2022/3/11 13:33
 * Version:1.0-SNAPSHOT
 */
@Controller
@SessionAttributes("user")
@RequestMapping("/session")
public class SessionController {

    @RequestMapping("/f1")
    public String f1(HttpSession session){
        User user = new User();
        user.setUsername("admin");
        session.setAttribute("user",user);
        return "scope";
    }

    @RequestMapping("/f2")
    public String f2(HttpSession session){
        User user = (User) session.getAttribute("user");
        System.out.println(user.getUsername());
        return "scope";
    }


    // Expected session attribute 'user'
    // 如果此时参数被@ModelAttribute进行标注
    // 此时主要操作的session作用域
    // 操作完成之后会将操作的数据在request作用域中进行备份
    @RequestMapping("/f3")
    public String f3(@ModelAttribute User user){
        // 此时运行时会优先从session中获取数据
        // 如果session此时没有数据,则直接报错
        user.setUsername("alice");
        return "scope";
    }

    // 当参数没有被@ModelAttribute注解所标注时
    // 表示当前主要操作的是request作用域
    // 操作完成之后会将操作的数据在session作用域中进行备份
    @RequestMapping("/f4")
    public String f4(User user){
        // 此时运行时会优先从request中获取数据
        // 如果request此时没有数据,不会报错
        // 当操作request作用域的时候,本身就会进行实例化
        // 相当于实现了User user = new User()
        // request.setAttribute("user",user)
        // 因此,操作request作用域的时候,如果没有数据
        // 则会初始化一个新的数据保存到request作用域中
        // 将初始化的数据备份到session中
        // 此时再次访问session作用域取值的时候,则会取出当前的数据
        user.setUsername("alice");
        return "scope";
    }

    @RequestMapping("/f5")
    public String f5(HttpSession session){
        // 当类被@SessionAttributes进行标注的时候
        // 无法再使用原来的方式进行session清除
        // 只有当类没有被@SessionAttributes进行标注的时候
        // 才能使用原来的方式进行清除
        session.invalidate();
        return "scope";
    }

    @RequestMapping("/f6")
    public String f6(SessionStatus sessionStatus){
        // 当类被@SessionAttributes标注的时候
        // 需要使用由Spring所提供的SessionStatus对象中的setComplete方法进行清除
        // 该方法只会清除session中的数据
        // 而对request作用域中的数据没有影响
        sessionStatus.setComplete();
        return "scope";
    }
}
